package com.specter.dev.docs.builder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.specter.utils.DOMUtils;
import com.specter.utils.StringUtils;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * Note:代码生成器配置文件解析类<br/>
 * 默认地址为：dir:/src/test/resources/config/specter-dev-docs.xml
 * 
 * @author Liang.Wang
 * @version Mar 23, 2017
 */
@Slf4j
public class GenConfiguration {
	public static final String DEFAULT_CFG = "dir:/src/test/resources/config/specter-dev-docs.xml";

	protected List<JApi> japis;

	/**
	 * 编译主配置文件，生成相应的实体对象
	 * 
	 * @param cfg 主配置文件的路径地址
	 */
	public GenConfiguration(String cfg) {

		cfg = StringUtils.isBlank(cfg) ? DEFAULT_CFG : cfg;// 项目根路径
		log.info("读取配置文件(请确保存在)：{}", DEFAULT_CFG);
		Element generator = DOMUtils.read(cfg).getDocumentElement();

		// japi element
		japis = new ArrayList<>();
		NodeList japiNode = generator.getElementsByTagName("japi");
		for (int i = 0; i < japiNode.getLength(); i++) {
			Element m = (Element) japiNode.item(i);// the module element
			JApi japi = new JApi();

			// meta element
			japi.metas = new HashMap<>();
			japi.metas.put("name", m.getAttribute("name"));
			NodeList metaNode = m.getElementsByTagName("meta");
			for (int j = 0; j < metaNode.getLength(); j++) {
				Element p = (Element) metaNode.item(j);// the property element
				String v = p.getAttribute("value");
				v = StringUtils.isBlank(v) ? p.getTextContent() : v;
				japi.metas.put(p.getAttribute("name"), v);
			}

			// input element
			japi.inputs = new ArrayList<>();
			NodeList inputNode = m.getElementsByTagName("input");
			for (int j = 0; j < inputNode.getLength(); j++) {
				Element l = (Element) inputNode.item(i);// the link element
				JApiInput link = new JApiInput();
				link.typ = l.getAttribute("typ");
				link.src = l.getAttribute("src");
				link.tgt = l.getAttribute("tgt");
				link.fix = l.getAttribute("fix");
				japi.inputs.add(link);
			}

			// output element
			japi.outputs = new ArrayList<>();
			NodeList outputNode = m.getElementsByTagName("output");
			for (int j = 0; j < outputNode.getLength(); j++) {
				Element o = (Element) outputNode.item(j);// the output element
				JApiOutput output = new JApiOutput();
				output.base = o.getAttribute("base");
				output.pkg = o.getAttribute("package");

				// file element
				output.files = new ArrayList<>();
				NodeList fileNode = o.getElementsByTagName("file");
				for (int k = 0; k < fileNode.getLength(); k++) {
					Element of = (Element) fileNode.item(k);// the file element
					JApiOutputFile mof = new JApiOutputFile();
					mof.pkg = of.getAttribute("package");
					mof.name = of.getAttribute("name");
					mof.ftl = of.getAttribute("ftl");
					output.files.add(mof);
				}
				japi.outputs.add(output);
			}
			japis.add(japi);
		}
	}

	/** ====== 配置文件元素对应的 Java Bean ====== **/
	@Data
	public class JApi {
		private Map<String, Object> metas;// 描述文件
		private List<JApiInput> inputs;// 输入设置
		private List<JApiOutput> outputs;// 输出设置
	}

	@Data
	public class JApiInput {
		private String typ;
		private String src;
		private String tgt;
		private String fix;
	}

	@Data
	public class JApiOutput {
		private String base;
		private String pkg;
		private List<JApiOutputFile> files;
	}

	@Data
	public class JApiOutputFile {
		private String pkg;
		private String name;
		private String ftl;
	}

}
